<?php

namespace Data;

class Category extends Base {

	static private $all;

	const TYPE_MULTIPLE = 1;

	const TYPE_SINGLE = 2;

	public function getCategoryByName($name) {
		$condition = array('CategoryName' => $name);
		$category = $this->where($condition)->findOne();
		return $category;
	}

	public function getCategoryById($id) {
		$condition = array('CategoryId' => (int) $id);
		$category = $this->where($condition)->findOne();
		return $category;
	}

	public function getCategoryByIds($ids) {
		$condition = array('CategoryId in' => $ids);
		$category = $this->where($condition)->order('Sort desc, CategoryId asc')->findAll('CategoryId');
		return $category;
	}

	public function getAll() {
		if (self::$all) {
			return self::$all;
		}
		self::$all = $this->order('Sort desc, CategoryId asc')->findAll('CategoryId');
		return self::$all;
	}

	public function getLevelCategories() {
		$all = $this->getAll();
		$levelArr = array();
		foreach ($all as $val) {
			if (!isset($val['List'])) {
				$val['List'] = array();
			}
			$level = $this->getLevel($all, $val['Pid']);
			$levelArr[$level][$val['CategoryId']] = $val;
		}
		krsort($levelArr);
		for ($i = count($levelArr); $i > 0; $i--) {
			$arr = $levelArr[$i];
			$level = $i;
			if ($level == 1) {
				continue;
			}
			foreach ($arr as $cid => $v) {
				$pInfo = &$levelArr[$level - 1][$v['Pid']];
				$pInfo['List'][$v['CategoryId']] = $v;
			}
		}
		$result = !empty($levelArr[1]) ? $levelArr[1] : array();

		return $result;
	}

	public function getIdsByPid($categoryId) {
		if (!$categoryId) {
			return array();
		}
		$this->getIdsByPidWhile($categoryId, true, $result);
		return $result;
	}

	public function getParentInfoById($categoryId) {
		$all = $this->getAll();
		$id = $categoryId;
		$result = array();
		while (true) {
			if (empty($all[$id])) {
				return array();
			}
			$current = $all[$id];
			array_unshift($result, $current);
			$pid = $current['Pid'];
			if ($pid) {
				$id = $pid;
			} else {
				break;
			}
		}
		return $result;
	}

	public function getParentInfoByIds($categoryIds) {
		$all = $this->getAll();
		$tmp = array();
		foreach ($categoryIds as $categoryId) {
			$id = $categoryId;
			while (true) {
				if (empty($all[$id])) {
					return array();
				}
				$current = $all[$id];
				$tmp[$current['CategoryId']] = $current;
				$pid = $current['Pid'];
				if ($pid) {
					$id = $pid;
				} else {
					break;
				}
			}
		}
		$levelArr = array();
		foreach ($tmp as $val) {
			if (!isset($val['List'])) {
				$val['List'] = array();
			}
			$level = $this->getLevel($tmp, $val['Pid']);
			$levelArr[$level][$val['CategoryId']] = $val;
		}
		krsort($levelArr);
		for ($i = count($levelArr); $i > 0; $i--) {
			$arr = $levelArr[$i];
			$level = $i;
			if ($level == 1) {
				continue;
			}
			foreach ($arr as $cid => $v) {
				$pInfo = &$levelArr[$level - 1][$v['Pid']];
				$pInfo['List'][$v['CategoryId']] = $v;
			}
		}
		$result = !empty($levelArr[1]) ? $levelArr[1] : array();
		return $result;
	}

	private function getIdsByPidWhile($categoryId, $isId = false, &$result = array()) {
		$result[$categoryId] = $categoryId;
		if ($categoryId == 0) {
			return;
		}
		$all = $this->getAll();
		$pidToArr = array();
		foreach ($all as $val) {
			$pidToArr[$val['Pid']][$val['CategoryId']] = $val;
		}
		if (!empty($pidToArr[$categoryId])) {
			$info = $pidToArr[$categoryId];
			foreach ($info as $val) {
				if ($isId) {
					$result[$val['CategoryId']] = $val['CategoryId'];
				} else {
					$result[$val['CategoryId']] = $val;
				}
				$this->getIdsByPidWhile($val['CategoryId'], $result);
			}
		}
	}

	private function getLevel($all, $pid, $level = 0) {
		$level++;
		if (!$pid) {
			return $level;
		}
		$pPid = $all[$pid]['Pid'];
		return $this->getLevel($all, $pPid, $level);
	}

	public function updateById($data, $id) {
		$this->where(array('CategoryId' => $id))->update($data);
	}

	public function add($data) {
		$this->insert($data);
	}
}